package com.jwpdk.dbframework;

import org.apache.log4j.Logger;

import com.jwpdk.appframework.cache.CacheFactory;
import com.jwpdk.appframework.cache.impl.SQLMapCache;
import com.jwpdk.appframework.data.DataMap;
import com.jwpdk.appframework.data.IData;
import com.jwpdk.appframework.data.IDataList;
import com.jwpdk.common.Config;
/**
 * 
 * @author 王志伟
 *
 */
public class SqlMap {

	private final Logger	log			= Logger.getLogger(this.getClass());
	private Config			config		= Config.getInstance();
	private static IData	catchMap	= null;
	DaoManager				daoManager;

	/**
	 * 按照事务名处理
	 * @param transactionName
	 * @throws Exception
	 */
	public SqlMap(String transactionName) throws Exception {
		daoManager = new DaoManager(transactionName);
		init();
	}

	/**
	 * 按照传递的事务处理
	 * @param transaction
	 * @throws Exception
	 */
	public SqlMap(Transaction transaction) throws Exception {
		daoManager = new DaoManager(transaction);
		init();
	}

	/**
	 * 构造器，如未启用SQLMAP映射则抛出异常。 当前连接处理
	 * @throws Exception
	 */
	public SqlMap() throws Exception {
		daoManager = new DaoManager();
		init();
	}

	private void init() throws Exception {
		if ( config.isNonSqlMap() ) {
			Exception exception = new Exception("未启用SQLMAP映射，请查看配置文件！");
			log.error(exception);
			throw exception;
		}
		// 如果为DEBUG模式 则重新加载配置文件、并重新加载数据
		if ( config.getSysMode().equalsIgnoreCase(Config.SYSTEM_MODE_DEBUG) ) {
			CacheFactory.getInstance().reLoadById(SQLMapCache.SQLMAP_CACHE_ID);
			catchMap = CacheFactory.getInstance().get(SQLMapCache.SQLMAP_CACHE_ID);
		}

		// 缓存对象如果为NULL 则从工厂获取。
		if ( catchMap == null ) {
			catchMap = CacheFactory.getInstance().get(SQLMapCache.SQLMAP_CACHE_ID);
		}
	}

	/*
	@SuppressWarnings("unchecked")
	public static void main(String[] args) throws Exception {
		Transaction transaction1 = new Transaction();
		TransactionManager transactionManager = TransactionManager.getInstance();
		transactionManager.beginTransaction(transaction1);

		Transaction transaction = new Transaction("jsptag");
		transactionManager = TransactionManager.getInstance();
		transactionManager.beginTransaction(transaction);
		SqlMap sqlMap = new SqlMap();
		IData iData = new DataMap();
		iData.put("parent_id","0");
		IDataList iDataList = sqlMap.iSelect("bz",iData);
		System.out.println(iDataList);
		transactionManager.endTransaction(transaction);
		transactionManager.endTransaction(transaction1);
	}
	 */
	/**
	 * 根据SQL映射查询
	 * @param sqlref
	 * @return
	 */
	public IDataList iSelect(String sqlref) throws Exception {
		String stmt = getSqlmapStmt(sqlref);
		SQL sql = new SQL(stmt);
		return daoManager.executeQuery(sql);
	}

	/**
	 * 根据SQL映射查询
	 * @param sqlref sql映射
	 * @param param 参数
	 * @return
	 */
	public IDataList iSelect(String sqlref, IData param) throws Exception {
		String stmt = getSqlmapStmt(sqlref);
		SQL sql = getSQL(stmt,param);
		return daoManager.executeQuery(sql);
	}

	/**
	 * 执行SQL映射 CUDFP
	 * @param sqlref
	 * @return M
	 */
	public IData iExecute(String sqlref) throws Exception {
		return iExecute(sqlref,null);
	}

	/**
	 * 执行SQL映射 CUDFP
	 * @param sqlref
	 * @param param
	 * @return M
	 */
	@SuppressWarnings("unchecked")
	public IData iExecute(String sqlref, IData param) throws Exception {
		if ( log.isDebugEnabled() ) {
			log.debug("SqlRef=" + sqlref);
			log.debug("param=" + param);
		}
		IData iData = new DataMap();
		String stmt = getSqlmapStmt(sqlref);
		int i = 0;
		switch ( getSqlType(sqlref) ) {
			case 'C' :
			case 'U' :
			case 'D' : {
				SQL sql = getSQL(stmt,param);
				i = daoManager.executeUpdate(sql);
				iData.put("RESULT",i);
				break;
			}
			case 'F' :
				break;
			case 'P' :
				break;
			default:
				break;
		}

		return iData;

	}

	/**
	 * 获取映射SQL对象
	 * @return
	 * @throws Exception
	 */
	private String getSqlmapStmt(String sqlref) throws Exception {
		loadCache(sqlref);
		IData iData = (IData) catchMap.get(sqlref);
		return iData.getString("SQL_STMT");
	}

	/**
	 * 获取SQL类型
	 * @param sqlref
	 * @return
	 * @throws Exception
	 */
	private char getSqlType(String sqlref) throws Exception {
		loadCache(sqlref);
		IData iData = (IData) catchMap.get(sqlref);
		return iData.getChar("SQL_TYPE");
	}

	/**
	 * 检查缓存是否存在，判断是否需要加载缓存。
	 * @param sqlref
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	private void loadCache(String sqlref) throws Exception {
		try {// 如果不存在则或者DEBUG模式则查询最新的记录
			if ( !catchMap.containsKey(sqlref) || config.getSysMode().equalsIgnoreCase(Config.SYSTEM_MODE_DEBUG) ) {
				IData iData = daoManager.getSqlMapData(sqlref);
				if ( iData.size() > 0 ) {
					catchMap.putAll(iData);
				} else {
					throw new Exception("未找到映射配置【" + sqlref + "】");
				}

			}
		} catch ( Exception e ) {
			log.error(e);
			throw e;
		}
	}

	private SQL getSQL(String sql, IData param) {
		SQL sqlParameter = new SQL(sql);
		if ( param != null ) {
			String[] names = param.getNames();
			for (int i = 0; i < names.length; i++) {
				sqlParameter.set(names[i],param.get(names[i]));
			}
		}
		return sqlParameter;
	}
}
